
from tortoise.expressions import Q

from datetime import datetime

from tortoise.functions import Sum

from app.core.crud import CRUDBase
from app.models.marketing import Integral
from app.schemas.marketing import IntegralCreate ,IntegralUpdate
from app.controllers.customer.users import users_controller


class IntegralController(CRUDBase[Integral, IntegralCreate, IntegralUpdate]):
    def __init__(self):
        super().__init__(model=Integral)

    async def do_list(self, page: int, page_size: int, search: Q = Q()):
        query = self.model.filter(search)
        total = await query.count()
        objs =  await query.offset((page - 1) * page_size).limit(page_size).order_by('-id')
        data = [await obj.to_dict() for obj in objs]
        return total, data

    async def do_detail(self ,data_id :int):
        obj = await self.get(id=data_id)
        data = await obj.to_dict()
        return data

    async def do_create(self, obj_in: IntegralCreate):
        await self.create(obj_in=obj_in)
        price = await users_controller.update_money(type=2, user_id=obj_in.user_id)
        return price

    async def do_update(self, obj_in: IntegralUpdate):
        await self.update(id=obj_in.id, obj_in=obj_in)
        await users_controller.update_money(type=2, user_id=obj_in.user_id)
        return True

    async def do_delete(self, data_id: int):
        user_id = await self.model.filter(id=data_id).first().values("user_id")
        await self.remove(id=data_id)
        await users_controller.update_money(type=2, user_id=user_id['user_id'])
        return True

    async def do_user_info(self, user_id: int):
        now = datetime.now()
        query = self.model.filter(user_id=user_id).filter(Q(expire_at__isnull=True) | Q(expire_at__gte=now))

        # Get add_price with default value 0 if None
        add_result = await query.filter(direction=1).annotate(total=Sum("price")).first().values("total")
        add_price = add_result['total'] if add_result and add_result['total'] else 0

        # Get reduce_price with default value 0 if None
        reduce_result = await query.filter(direction=2).annotate(total=Sum("price")).first().values("total")
        reduce_price = reduce_result['total'] if reduce_result and reduce_result['total'] else 0

        price = add_price - reduce_price
        return price

integral_controller =IntegralController()
